package com.agileai.esb.smc.service;

import java.util.List;

import javax.xml.soap.SOAPException;

import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.esb.smc.bizmoduler.sysres.SysUserManage;
import com.agileai.hotweb.common.BeanFactory;
import com.agileai.util.CryptionUtil;

public class ServiceAuthHandler extends AbstractPhaseInterceptor<SoapMessage> {
	private static final Logger logger = Logger.getLogger(ServiceAuthHandler.class);
	public static final String XML_NAMESPACEUR_ATT = "http://esb.agileai.com/wsauth";
	public static final String XML_AUTHENTICATION_EL = "authentication";
	public static final String XML_USERID_EL = "userId";
	public static final String XML_PASSWORD_EL = "password";	
	
	public ServiceAuthHandler() {
		super(Phase.PRE_INVOKE);
	}
	
	public void handleMessage(SoapMessage message) throws Fault{
		List<Header> headers = message.getHeaders();
		SoapHeader soapHeader = null;
		if (headers != null){
			soapHeader = (SoapHeader)headers.get(0);
			 try {
				Element authElement =  (Element)soapHeader.getObject();
				if (authElement != null){
					NodeList userIdNodes = authElement.getElementsByTagName(XML_USERID_EL);
					NodeList pwdNodes = authElement.getElementsByTagName(XML_PASSWORD_EL);
					if (null != userIdNodes  && pwdNodes != null){
						String userId = userIdNodes.item(0).getTextContent();
						String userPwd = pwdNodes.item(0).getTextContent();

						SysUserManage sysUserManage = (SysUserManage)BeanFactory.instance().getBean("sysUserManageService");
						DataRow row = sysUserManage.getRecordByCode(new DataParam("USER_CODE",userId));
						String encryptedPassword = CryptionUtil.md5Hex(userPwd);
						if (row != null && !row.isEmpty()){
							String userState = row.stringValue("USER_STATE");
							String password = row.stringValue("USER_PWD");
							if (password.equals(encryptedPassword) && "enable".equals(userState)){
								String userType = row.getString("USER_TYPE");
								if ("admin".equals(userId)){
									logger.debug(userId + " auth successfully !");
								}
								else if ("developer".equals(userType)){
									logger.debug(userId + " auth successfully !");
								}
								else{
									SOAPException soapExc = new SOAPException(userId + " auth failed !");
									throw new Fault(soapExc);
								}
							}else{
								SOAPException soapExc = new SOAPException(userId + " auth failed !");
								throw new Fault(soapExc);
							}
						}							
					} else {
						SOAPException soapExc = new SOAPException("password is not valid !");
						throw new Fault(soapExc);
					}
				}else{
					SOAPException soapExc = new SOAPException("auth element is not exsits !");
					throw new Fault(soapExc);
				}					 
			} catch (Exception e) {
				SOAPException soapExc = new SOAPException(e.getLocalizedMessage());
				throw new Fault(soapExc);
			}
		}else{
			SOAPException soapExc = new SOAPException("auth header is not exsits !");
			throw new Fault(soapExc);
		}
	}
}